<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Client/Serveur FTP simplifié en RPC-Groupe 1-Réalisation Pratique</title>
<meta http-equiv="Content-Language" content="English" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<link rel="stylesheet" type="text/css" href="style.css" media="screen" />
</head>
<body>

<div id="wrap">

<div id="header">
<h1>&nbsp;</h1>
<h1>&nbsp;</h1>
<h1><a href="#">Client/Serveur FTP simplifié en RPC</a></h1>
<h2>Groupe 1</h2>
</div>

<div id="right">

<h2><a href="realisation.html"><strong>Réalisation Pratique</strong></a></h2>
<div class="articles">
<p>Dans le cadre de ce  Travail Pratique, nous avons utilisé l'outil <em>rpcgen</em>, pour générer généré  les souches client et serveur. Ci dessous figure le listing de notre fichier de  spécification</p>
<table border="1" cellspacing="0" cellpadding="0">
  <tr>
    <td valign="top"><em>const    BUFF_SIZE = 4096;      /* longueur    buffer = 4KO */</em><br />
      <em>const FN_SIZE = 256; /*    longueur filename max = 256 */</em>
      <p><em>struct open_file {</em><br />
        <em>            string   filename&lt;FN_SIZE&gt;;</em><br />
        <em>            bool     rw;       /*    r=FALSE(0), w=TRUE(1) */</em><br />
        <em>};</em><br />
        <em>struct data_o {                         /*    structure de donnÃ©es pour WRITE */</em><br />
        <em>int        fd;</em><br />
        <em>            string   buf&lt;BUFF_SIZE&gt;;</em><br />
        <em>int        len;</em><br />
        <em>};</em></p>
      <p><em>struct data_i {                 /* structure de donnÃ©es    pour READ */</em><br />
        <em>           string  buf&lt;BUFF_SIZE&gt;;</em><br />
        <em>           int     len;</em><br />
        <em>};</em></p>
      <p><em>struct user_parameter {</em><br />
        <em>            int    uid;</em><br />
        <em>            int    gid;</em><br />
        <em>};</em><br />
        <em>program PROG {</em><br />
        <em>            version    VERS {</em><br />
        <em>                        string    PWD(void) = 1; /* proc #1 */</em><br />
        <em>                        bool    CD(string) = 2;    /* proc #2 */</em><br />
        <em>                        string    LS(void) = 3;     /* proc #3 */</em><br />
        <em>/*                     file    GET(string) = 4;    /* proc #4 */</em><br />
        <em>/*                     int    PUT(string) = 5;     /* proc #5 */</em><br />
        <em>                        int    OPEN(open_file) = 4;</em><br />
        <em>                        data_i    READ(int) = 5;</em><br />
        <em>                        int    WRITE(data_o) = 6;</em><br />
        <em>                        int    CLOSE(int) = 7;</em><br />
        <em>                        int    BYE(void) = 8;        /* proc #8 */</em><br />
        <em>                        user_parameter    GET_PARAM(string) = 9; /* proc #9*/</em><br />
        <em>int CHECK(void) = 10; /* verifi si l'utilisateur a le droit    d'ecriture dans un repertoire*/</em><br />
        <em>            } = 1;                                       /* vers    #1 */</em><br />
        <em>} = 0x12345678;                                             /*    prog num*/</em></p></td>
  </tr>
</table>
<p><strong>Gestion de l'authentification des utilisateurs</strong><br />
  Le but de  l'authentification ici est de contrôler les différents utilisateurs qui se  connectent au système ainsi chaque utilisateur disposant d'un  compte sur le serveur est automatiquement  redirigé vers son répertoire de travail personnel, tandis que les utilisateurs  ne disposant pas de compte sur le serveur sont automatiquement redirigé vers un  répertoire public dans lequel il ne peut pas écrire. Avant d'expliquer le  principe d'implémentation de cette sécurité, faisons un bref aperçu des  mécanismes de sécurité offert par les RPC.   <br />
  Par  défaut, il n'y a pas information dans une requête RPC permettant au serveur  d'identifier le client. Le serveur répond donc aux requêtes du client sans se  soucier de qui il est. C'est ce que l'on appelle authentification nulle (<em>null  authentification ou AUTH_NONE</em>).<br />
  Afin de  sécuriser notre serveur, nous avons implémenté le plus simple des mécanismes  d'authentification disponible sur le système UNIX il s'agit de AUTH_UNIX.              <br />
  Pour ce  faire, nous avons définie les structures et les fonctions suivantes toutes  implémentée au niveau du serveur.   </p>
<table border="1" cellspacing="0" cellpadding="0">
  <tr>
    <td valign="top"><br />
      struct user_parameter {<br />
      <em>int uid;</em><br />
      <em>int gid;</em><br />
      <em>};</em></td>
    </tr>
</table>
<p><em>Cette  structure contient le uid et le gid d'un utilisateur donné</em></p>
<table border="1" cellspacing="0" cellpadding="0">
  <tr>
    <td valign="top"><p><em>user_parameter GET_PARAM(string) = 9; </em><br />
      <em>int CHECK(void) = 10;</em></p></td>
    </tr>
</table>
<p>La  fonction  <em>get_param</em> prend en  entrée un nom d'utilisateur et renvoie en retour une structure du type  <em>user_parameter</em> (remarquer que c'est un appel distant) contenant le uid et le gid  sur le serveur de l'utilisateur dont le nom de compte est passé en paramètre.<br />
  Tandis que la  fonction CHECK vérifie tout simplement si l'utilisateur qui réalise l'opération  put a le droit d'écriture dans le répertoire courant de l'environnement du  serveur.   <br />
  Une fois uid et le gid de  l'utilisateur qui essaie de se connecté obtenu, on fixe le mécanisme  d'authentification au niveau du client de la manière.  </p>
<table border="1" cellspacing="0" cellpadding="0">
  <tr>
    <td valign="top"><br />
      <strong><em>struct</em></strong><em> user_parameter* param =    get_param_1(&amp;argv[2],client);     </em><br />
      <strong><em>if</em></strong><em>(param -&gt;uid &lt; 0){   </em><br />
      <em>/* Si l'utilisateur n'est pas valide, on l'envoie dans le    repertoire public */</em><br />
      <em>printf(</em><em>&quot;Invalid user !!\n&quot;</em><em>);</em><br />
      <em>printf(</em><em>&quot;Redirect to public !! \n&quot;</em><em>);</em><br />
      <em>}</em><br />
      <strong><em>else</em></strong><em>{</em><br />
      <em>gid_t aup_gids[5];</em><br />
      <em>aup_gids[0]=(</em><strong><em>int</em></strong><em>)param-&gt;gid;</em><br />
      <strong><em>int</em></strong><em> len;</em><br />
      <strong><em>if</em></strong><em> ((len = getgroups(NGRPS, aup_gids)) &lt; 0) {</em><br />
      <em>//printf(&quot;failed in    getgroups()!!\n&quot;);</em><br />
      <em>exit(2);</em><br />
      <em>}</em><strong><em>else</em></strong><br />
      <em>auth_destroy(client-&gt;cl_auth);</em><br />
      <em>len = (len &gt; 16) ? 16 : len; </em><br />
      <em>/* On fixe l'authentification du client*/</em><br />
      <em>//nouvelle mÃ©canismes d'authentification</em><br />
      <em>//les arguments param-&gt;uid et param-&gt;gid sont    respectivement le uid et le gid de </em><br />
      <em>//l'utilisateur dont le non de compte a ete passe en qrgument</em><br />
      <em>client-&gt;cl_auth = (AUTH*)    authunix_create(argv[1],(</em><strong><em>int</em></strong><em>)param-&gt;uid,(</em><strong><em>int</em></strong><em>)param-&gt;gid,len, aup_gids); </em><br />
      <strong><em>if</em></strong><em> (client-&gt;cl_auth == (AUTH *)</em><strong><em>NULL</em></strong><em>)    {</em><br />
      <em>fprintf(stderr, </em><em>&quot;authunix_create failed!!\n&quot;</em><em>);</em><br />
      <em>exit(1);</em><br />
      <em>}</em></td>
  </tr>
</table>
<p>                    Ainsi, si un utilisateur n'a  pas un nom de compte valide <em>(param -&gt;uid &lt; 0) </em>le mécanisme  d'authentification reste celui par défaut.<br />
  Le  serveur se base sur ces informations pour gérer les droits d'accès à ses  différents répertoire. Ainsi un utilisateur ayant un compte valide sera dirigé  dans son répertoire personnel.<br />
  Remarque  cette opération n'est faite que lors de la connexion de l'utilisateur.   </p>
<table border="1" cellspacing="0" cellpadding="0">
  <tr>
    <td valign="top"><br />
      <strong><em>if</em></strong><em>(req-&gt;rq_cred.oa_flavor ==    AUTH_UNIX){</em><br />
      <em>//                  fputs(&quot;ICI&quot;,stdout);</em><br />
      <em>au = (</em><strong><em>struct</em></strong><em> authunix_parms    *)req-&gt;rq_clntcred;</em><br />
      <strong><em>char</em></strong><em> st[]={</em><em>'.'</em><em>,</em><em>'\0'</em><em>};</em><br />
      <strong><em>int</em></strong><em> s = stat(st,&amp;buf);</em><br />
      <em>//fputs(&quot;ICI&quot;,stdout);</em><br />
      <strong><em>if</em></strong><em>(((</em><strong><em>long</em></strong><em>)au-&gt;aup_uid == (</em><strong><em>long</em></strong><em>)buf.st_uid) || ((</em><strong><em>long</em></strong><em>)au-&gt;aup_gid == (</em><strong><em>long</em></strong><em>)buf.st_gid)){</em><br />
      <br />
      <strong><em>struct</em></strong><em> passwd *pass = getpwuid((</em><strong><em>long</em></strong><em>)au-&gt;aup_uid);</em><br />
      <em>chdir(pass-&gt;pw_dir);</em><br />
      <em>}</em><br />
      <em>}</em><br />
      <strong><em>else</em></strong><em>{                 </em><br />
      <em>chdir(</em><em>&quot;PUBLIC&quot;</em><em>);</em><br />
      <em>}</em></td>
    </tr>
</table>
<p><strong>Description des  classes serveurs et client</strong></p>
<ol>
              Dans ce paragraphe, nous présentons  quelques fonctions utile dans la réalisation de notre programme.<br />
  Le client qui implémente les  opérations <em>lls, lcd et lpwd</em> est constitué essentiellement d'une boucle  for qui tourne indéfiniment en attente d'ordres provenant de  l'utilisateur.  Les opérations  implémentées par le serveur ou par appel de procédure distante. Ci-dessus  figure le prototype des fonctions implémentées par le client.
</ol>
<table border="1" cellspacing="0" cellpadding="0">
  <tr>
    <td valign="top"><br />
      <em>/* La    fonction ci-dessous lit le nom de la machine locale*/</em><br />
      <strong><em>void</em></strong><em> name(</em><strong><em>char</em></strong><em>*s1) //permet    d'extraire le nom de l'hôte local </em><br />
      <em>//les objets sessions sont    utilisés pour gérer les sessions utilisateur</em><br />
      <strong><em>int</em></strong><em> generate_session_id() </em><br />
      <em>//La méthode    ci-dessous exécute la commande pwd </em><br />
      <strong><em>void</em></strong><em> pwd_command(CLIENT *m_client)</em><br />
      <strong><em>void</em></strong><em> lpwd_command()</em><br />
      <strong><em>void</em></strong><em> ls_command(CLIENT *m_client)</em><br />
      <strong><em>void</em></strong><em> lls_command() </em><br />
      <strong><em>void</em></strong><em> put_command(</em><strong><em>const</em></strong><em> std::string&amp; file_name, CLIENT *m_client)</em><br />
      <strong><em>void</em></strong><em> lcd_command(</em><strong><em>const</em></strong><em> std::string&amp; repertoire)</em><br />
      <strong><em>void</em></strong><em> get_command(</em><strong><em>const</em></strong><em> std::string&amp; file_name, CLIENT    *m_client)</em></td>
    </tr>
</table>
<p>              <br />
  Le serveur quant  lui s'exécute indéfiniment en répondant aux requêtes en provenance de multiples  clients qui lui sont connecté. Ci-dessous figure le prototype de fonctions  implémentées par le serveur </p>
<table border="1" cellspacing="0" cellpadding="0">
  <tr>
    <td valign="top"><br />
      <strong><em>void</em></strong><em> check_auth(</em><strong><em>struct</em></strong><em> svc_req *req) </em><br />
      <strong><em>char</em></strong><em> ** pwd_1_svc(</em><strong><em>void</em></strong><em> *data, </em><strong><em>struct</em></strong><em> svc_req *req)</em><br />
      <em>bool_t    * cd_1_svc(</em><strong><em>char</em></strong><em> **new_dir, </em><strong><em>struct</em></strong><em> svc_req *req)</em><br />
      <strong><em>char</em></strong><em> ** ls_1_svc(</em><strong><em>void</em></strong><em> *data, </em><strong><em>struct</em></strong><em> svc_req *req)</em><br />
      <strong><em>int</em></strong><em> * open_1_svc(open_file *file, </em><strong><em>struct</em></strong><em> svc_req *req)</em><br />
      <em>data_i    * read_1_svc(</em><strong><em>int</em></strong><em> *fd, </em><strong><em>struct</em></strong><em> svc_req *req)</em><br />
      <strong><em>int</em></strong><em> * write_1_svc(data_o *data_buffer, </em><strong><em>struct</em></strong><em> svc_req *req)</em><br />
      <strong><em>int</em></strong><em> * close_1_svc(</em><strong><em>int</em></strong><em> *file_handle, </em><strong><em>struct</em></strong><em> svc_req *req)</em><br />
      <strong><em>struct</em></strong><em> user_parameter * get_param_1_svc(</em><strong><em>char</em></strong><em> **param, </em><strong><em>struct</em></strong><em> svc_req *req)</em><br />
      <strong><em>int</em></strong><em> * check_1_svc(</em><strong><em>void</em></strong><em> *, </em><strong><em>struct</em></strong><em> svc_req *req)</em></td>
    </tr>
</table>
<p>&nbsp;</p>
</div>
<h2>&nbsp;</h2>
</div>

<div id="left"> 

<h3>Categories :</h3>
<ul>
<li><a href="index.html">Introduction</a></li> 
<li><a href="specification.html">Spécification & Conception</a></li>
<li><a href="realisation.html">Réalisation pratique</a></li> 
<li><a href="resultat.html">Résultats et analyse</a></li>
<li><a href="conclusion.html">Conclusion</a></li> 
 <li><a href="membres.html">Membres de l'équipe 1</a></li> 

</ul>



</div>
<div style="clear: both;"> </div>

<div id="footer">
Designed by <a href="http://www.free-css-templates.com/">Free CSS Templates</a></div>
</div>


</body>
</html>